package com.kongjs.application.advice;

import com.kongjs.application.exception.AccountException;
import com.kongjs.application.exception.ApiParamCheckException;
import com.kongjs.application.exception.TokenException;
import com.kongjs.common.rest.advice.GlobalRestControllerAdvice;
import com.kongjs.common.rest.annotation.Rest;
import com.kongjs.common.rest.model.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;

@Slf4j
@RestControllerAdvice(annotations = Rest.class, basePackages = "com.kongjs.application.controller.rest")
public class ApiControllerAdvice extends GlobalRestControllerAdvice {

    @ExceptionHandler(value = AuthenticationException.class)
    public ResponseEntity<Object> handlerAuthenticationException(AuthenticationException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.FORBIDDEN, ex.getClass().getName(), null, ex.getMessage());
        return handleExceptionInternal(ex, error, headers, HttpStatus.FORBIDDEN, request);
    }

    @ExceptionHandler(value = AccessDeniedException.class)
    public ResponseEntity<Object> handlerAccessDeniedException(AccessDeniedException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.FORBIDDEN, ex.getClass().getName(), null, ex.getMessage());
        return handleExceptionInternal(ex, error, headers, HttpStatus.FORBIDDEN, request);
    }

    @ExceptionHandler(TokenException.class)
    public ResponseEntity<Object> handlerTokenException(TokenException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.FORBIDDEN, ex.getClass().getName(), null, ex.getMessage());
        return handleExceptionInternal(ex, error, headers, HttpStatus.FORBIDDEN, request);
    }

    @ExceptionHandler(value = ApiParamCheckException.class)
    public ResponseEntity<Object> handlerApiParamException(ApiParamCheckException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.BAD_REQUEST, ex.getClass().getName(), null, ex.getMessage());
        return handleExceptionInternal(ex, error, headers, HttpStatus.BAD_REQUEST, request);
    }

    @ExceptionHandler(AccountException.class)
    public ResponseEntity<Object> handlerAccountException(AccountException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getClass().getName(), null, ex.getMessage());
        return handleExceptionInternal(ex, error, headers, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }

    @ExceptionHandler(NullPointerException.class)
    public ResponseEntity<Object> handlerNullPointerException(NullPointerException ex, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getClass().getName(), null, "内部出现空参数");
        log.error("空指针异常",ex);
        return handleExceptionInternal(ex, error, headers, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }

    @ExceptionHandler(BadSqlGrammarException.class)
    public ResponseEntity<Object> handlerBadSqlGrammarException(BadSqlGrammarException ex,WebRequest request){
        HttpHeaders headers = new HttpHeaders();
        headers.setCacheControl(CacheControl.noCache());
        R error = error(ex, HttpStatus.INTERNAL_SERVER_ERROR, ex.getClass().getName(), null, "数据库操作异常");
        log.error("数据库操作异常",ex);
        return handleExceptionInternal(ex, error, headers, HttpStatus.INTERNAL_SERVER_ERROR, request);
    }
}
